package main

import (
	"fmt"
	"time"
)

func main() {
	//int初始值为0,string初始值为空字符串
	type Employee struct {
		ID        int
		Name      string
		Address   string
		DoB       time.Time
		Position  string
		Salary    int
		ManagerID int
	}
	var dilbert Employee
	dilbert.Name = "Bob"
	dilbert.Address = "BeiJing"
	dilbert.DoB = time.Now()
	position := &dilbert.Position
	*position = "Senior"
	dilbert.Salary = 5000
	fmt.Println(dilbert)

	var employeeOfTheMonth *Employee = &dilbert
	employeeOfTheMonth.Position += " team leader"
	fmt.Println(dilbert)
	a := []int{11, 2, 3, 4, 50, 6}
	fmt.Println(a)
	Sort(a)
	fmt.Println(a)
	fmt.Println(Scale(Point{1, 2}, 5)) // "{5 10}"

	//创建并初始化一个结构体变量，并返回结构体的地址
	pp := &Point{1, 2}
	fmt.Println(pp)

	//结构体比较
	p := Point{1, 2}
	q := Point{2, 1}
	fmt.Println(p.X == q.X && p.Y == q.Y) // "false"
	fmt.Println(p == q)                   // "false"

	//可比较的结构体类型和其他可比较的类型一样，可以用于map的key类型。
	type address struct {
		hostname string
		port     int
	}
	hits := make(map[address]int)
	fmt.Println(hits[address{"golang.org", 443}])
	hits[address{"golang.org", 443}]++
	fmt.Println(hits[address{"golang.org", 443}])

	//结构体的匿名函数
	type point struct {
		x, y int
	}
	type circle struct {
		point
		radius int
	}
	type wheel struct {
		circle
		spokes int
	}
	var w wheel
	w.x = 8
	w.y = 8
	fmt.Println(w)
	w = wheel{circle{point{6, 6}, 5}, 20}
	fmt.Println(w)
	fmt.Printf("%#v", w) //Printf函数中%v参数包含的#副词，它表示用和Go语言类似的语法打印值。对于结构体类型来说，将包含每个成员的名字
}

type Point struct{ X, Y int }

//较大的结构体通常会用指针的方式传入和返回
// 如果要在函数内部修改结构体成员的话，用指针传入是必须的；因为在Go语言中，所有的函
// 数参数都是值拷贝传入的，函数参数将不再是函数调用时的原始变量。

func Scale(p Point, factor int) Point {
	return Point{p.X * factor, p.Y * factor}
}

//使用一个二叉树来实现一个插入排排序,把切片值放在bst二叉排序树里，再把树放回切片，即实现排序
type tree struct {
	value       int
	left, right *tree
}

//Sort sorts values in place.
func Sort(values []int) {
	var root *tree
	for _, v := range values {
		root = add(root, v)
	}
	appendValues(values[:0], root)
}

// appendValues appends the elements of t to values in order
// and returns the resulting slice.
func appendValues(values []int, t *tree) []int {
	if t != nil {
		values = appendValues(values, t.left)
		values = append(values, t.value)
		values = appendValues(values, t.right)
	}
	return values
}

func add(t *tree, value int) *tree {
	if t == nil {
		// Equivalent to return &tree{value: value}.
		t = new(tree)
		t.value = value
		return t
	}
	if value < t.value {
		t.left = add(t.left, value)
	} else {
		t.right = add(t.right, value)
	}
	return t
}
